<?php
declare (strict_types=1);

namespace app\common\model;

class Area extends Base
{
    protected $name = 'area';

    public static function getArea($parent_code = 100000, $level = 1)
    {

        switch ($level) {
            case 1:
                $filed = 'province as title';
                break;
            case 2:
                $filed = 'city as title';
                break;
            case 3:
                $filed = 'district as title';
                break;
            case 4:
                $filed = 'town as title';
                break;
        }

        return parent::where(['parent_code' => $parent_code, 'level' => $level])
            ->field('code,' . $filed)->select();
    }

    public function getRegions(): array
    {
        try {
            $result = $this->field('code as id,parent_code as pid,level,province,city,district,uid,pasture_uid')->select()->toArray();

            return mergeArea($result);

        } catch (\Exception $e) {
            return [];
        }

    }

    public static function verifyUser($uid, $area_id, $level, $key = 'uid')
    {
        switch ($level) {
            case 1:
                $filed = 'province as title';
                break;
            case 2:
                $filed = 'concat(province, city) as title';
                break;
            case 3:
                $filed = 'concat(province, city, district) as title';
                break;
            case 4:
                $filed = 'concat(province, city, district, town) as title';
                break;
        }
        $info = parent::where([$key => $uid, 'level' => $level])->where('id', '<>', $area_id)->field($filed)->find();

        return $info;
    }

    public static function agentLevel($uid, $key = 'uid', $user_key = 'agent_level')
    {
        try {
            $user = User::find($uid);
            $level = parent::where([$key => $uid])->column('level');
            $level = array_values(array_unique($level));
            $count = count($level);
            if ($count >= 2) {
                $agent = 3;
            } elseif($count == 0) {
                $agent = 0;
            } else {
                $agent = in_array(2, $level)? 2: 1;
            }

            $user->$user_key = $agent;

            if($agent > 0){
                if($user_key == 'agent_level'){
                    $user->syn_level = $agent + 5;
                    if(($agent == 1 || $agent == 3) && !$user->district_time){
                        $user->district_time = time();
                        $user->exp_district_time = strtotime("+1 year");
                    }elseif(($agent == 2 || $agent == 3) && !$user->city_time){
                        $user->city_time = time();
                        $user->exp_city_time = strtotime("+1 year");
                    }
                }elseif($user_key == 'contract_agent_level'){
                    if(($agent == 1 || $agent == 3) && !$user->contract_district_time){
                        $user->contract_district_time = time();
                        $user->contract_exp_district_time = strtotime("+1 year");
                    }elseif(($agent == 2 || $agent == 3) && !$user->contract_city_time){
                        $user->contract_city_time = time();
                        $user->contract_exp_city_time = strtotime("+1 year");
                    }
                }elseif($user_key == 'pasture_agent_level'){
                    if(($agent == 1 || $agent == 3) && !$user->pasture_district_time){
                        $user->pasture_district_time = time();
                        $user->pasture_exp_district_time = strtotime("+1 year");
                    }elseif(($agent == 2 || $agent == 3) && !$user->pasture_city_time){
                        $user->pasture_city_time = time();
                        $user->pasture_exp_city_time = strtotime("+1 year");
                    }
                }
            }else{
                if($user_key == 'agent_level'){
                    $user->syn_level = $user->level_id;
                }
            }

            $user->save();

        } catch (\Exception $e) {

            return $e->getMessage();
        }

        return true;
    }

    public static function agentLog($uid, $area, $admin = [], $key = 'uid')
    {
        if($key == 'contract_uid'){
            $old_uid = $area->contract_uid;
            $type = 12;
            $note = '合约专区代理';
        }elseif($key == 'pasture_uid'){
            $old_uid = $area->pasture_uid;
            $type = 22;
            $note = '云牧场代理';
        }elseif($key == 'tillage_uid'){
            $old_uid = $area->tillage_uid;
            $type = 32;
            $note = '云耕科技代理';
        }else{
            $old_uid = $area->uid;
            $type = 2;
            $note = '商城代理';
        }
        $region = $area->city.$area->district;
        $old_user = User::find($old_uid)??'';
        $new_user = User::find($uid)??'';

        $before = $old_user ? $old_user->code.'-'.$old_user->nickname : '';
        $after = $new_user ? $new_user->code.'-'.$new_user->nickname : '';
        $intro = "{$region}的{$note}由【{$before}】变更为【{$after}】";

        UserLevelLog::create([
            'area_id' => $area->code,
            'type' => $type,
            'before_id' => $old_user ? $old_user->id : '',
            'after_id' => $new_user ? $new_user->id : '',
            'before' => $before,
            'after' => $after,
            'intro' => $intro,
            'admin_id' => $admin ? $admin['id'] : '',
            'admin_name' => $admin ? $admin['admin_name'] : '',
        ]);
    }

    /**
     * 增加地区数据统计(定时任务，每天凌晨00:10执行)
     */
    public static function addStatistics(): array
    {
        Order::with(['user'])->whereDay('pay_time', 'yesterday')->select()->each(function ($item){
            if($item->user->district){
                if($month = StatisticsAreaMonth::where(['district_code'=>$item->user->district, 'month'=>date("Y-m", $item->pay_time)])->find()){
                    $month->user_count ++;
                    $month->consume_sum += $item->real_amount;
                }else{
                    $month = StatisticsAreaMonth::create([
                        'district_code' => $item->user->district,
                        'district_name' => Area::where('code', $item->user->district)->value('concat_ws("", province,city,district) as district_name'),
                        'user_count' => 1,
                        'consume_sum' => $item->real_amount,
                        'year' => date("Y", $item->pay_time),
                        'month' => date("Y-m", $item->pay_time),
                    ]);
                }
                $userRate = self::getRate($item, 'user', 'month', $month->user_count);
                $consumeRate = self::getRate($item, 'consume', 'month', 0, $month->consume_sum);

                $month->user_add = $userRate[0];
                $month->user_rate = $userRate[1];
                $month->consume_add = $consumeRate[0];
                $month->consume_rate = $consumeRate[1];

                $month->save();

                if($year = StatisticsAreaYear::where(['district_code'=>$item->user->district, 'year'=>date("Y", $item->pay_time)])->find()){
                    $year->user_count ++;
                    $year->consume_sum += $item->real_amount;
                }else{
                    $year = StatisticsAreaYear::create([
                        'district_code' => $item->user->district,
                        'district_name' => Area::where('code', $item->user->district)->value('concat_ws("", province,city,district) as district_name'),
                        'user_count' => 1,
                        'consume_sum' => $item->real_amount,
                        'year' => date("Y", $item->pay_time),
                    ]);
                }

                $userRate = self::getRate($item, 'user', 'year', $year->user_count);
                $consumeRate = self::getRate($item, 'consume', 'year', 0, $year->consume_sum);

                $year->user_add = $userRate[0];
                $year->user_rate = $userRate[1];
                $year->consume_add = $consumeRate[0];
                $year->consume_rate = $consumeRate[1];

                $year->save();
            }
        });

        return ['code'=>1, 'msg'=>'done'];
    }

    private static function getRate($order, $type, $time, $user_count=0, $consume_sum=0)
    {
        if($time == 'month'){
            $last = StatisticsAreaMonth::where(['district_code'=>$order->user->district, 'month'=>date("Y-m", strtotime("-1 month", $order->pay_time))])->find();
        }else{
            $last = StatisticsAreaYear::where(['district_code'=>$order->user->district, 'year'=>date("Y", strtotime("-1 year", $order->pay_time))])->find();
        }

        if($type == 'user'){
            $add = $last ? $user_count - $last->user_count : $user_count;
            $rate = $last && $last->user_count > 0 ? round(100*$add/$last->user_count, 2) : '0.00';
        }else{
            $add = $last ? $consume_sum - $last->consume_sum : $consume_sum;
            $rate = $last && $last->consume_sum > 0 ? round(100*$add/$last->consume_sum, 2) : '0.00';
        }

        return [$add, $rate];
    }
}
